package com.qsxc.utils;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.qsxc.system.log.LogUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
 * @ClassName OSSClientUtil
 */
@Component
public class OSSClientUtil {
    static Log log = LogFactory.getLog(OSSClientUtil.class);

    @Value("${aliOssPrefix}")
    private String aliOssUrl;
    @Value("${aliOssPrefixLocal}")
    private String aliOssUrlLocal;

    private static String OSS_URL;
    private static String OSS_URL_LOCAL;

    private static String endpoint;
    private static String accessKeyId = "LTAI5tLXGwhPGsk9j9vd6oYh";
    private static String accessKeySecret = "tWQzZjLj4VMPLHtZi7yCQrEr23CJ7v";
    private static String bucketName = "fangtugy";
    private static String currentYYYYMM;

    @PostConstruct
    private void init() {
        OSS_URL_LOCAL = aliOssUrlLocal;
        OSS_URL = aliOssUrl;
        if (System.getProperty("os.name").toLowerCase().contains("win")) {
            endpoint = "oss-cn-hangzhou.aliyuncs.com";
        } else {
            endpoint = "oss-cn-hangzhou-internal.aliyuncs.com";
        }
        currentYYYYMM = DateTimeUtil.dateToString(new Date(), "yyyyMM") + "/";
    }

    public static String uploadByByte(byte[] bytes, String fileDir, String fileName) {
        return uploadFile2OSS(new ByteArrayInputStream(bytes), fileDir, fileName);
    }

    public static boolean deleteFile(String fileUrl) {
        OSSClient ossClient = null;
        try {
            ClientConfiguration conf = new ClientConfiguration();
            // 请求超时时间设置
            conf.setConnectionTimeout(5000);
            // 请求失败重试次数
            conf.setMaxErrorRetry(3);
            ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret, conf);
            ossClient.deleteObject(bucketName, fileUrl);
            return true;
        } catch (Exception e) {
            LogUtil.error("OOS删除图片异常", e);
            return false;
        } finally {
            assert ossClient != null;
            ossClient.shutdown();
        }
    }

    public static boolean moveFile(String fromUrl, String toUrl) {
        OSSClient ossClient = null;
        try {
            ClientConfiguration conf = new ClientConfiguration();
            // 请求超时时间设置
            conf.setConnectionTimeout(5000);
            // 请求失败重试次数
            conf.setMaxErrorRetry(3);
            ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret, conf);
            ossClient.copyObject(bucketName, fromUrl, bucketName, toUrl);
            ossClient.deleteObject(bucketName, fromUrl);
            return true;
        } catch (Exception e) {
            LogUtil.error("迁移图片", e);
            return false;
        } finally {
            assert ossClient != null;
            ossClient.shutdown();
        }
    }

    public static boolean backUp(List<String> urlList, String backPath) {
        OSSClient ossClient = null;
        try {
            ClientConfiguration conf = new ClientConfiguration();
            // 请求超时时间设置
            conf.setConnectionTimeout(5000);
            // 请求失败重试次数
            conf.setMaxErrorRetry(3);
            ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret, conf);
            for (String item : urlList) {
                ossClient.copyObject(bucketName, item, bucketName, backPath + (item.startsWith("/") ? item : "/" + item));
                ossClient.deleteObject(bucketName, item);
            }
            return true;
        } catch (Exception e) {
            LogUtil.error("迁移图片", e);
            return false;
        } finally {
            assert ossClient != null;
            ossClient.shutdown();
        }
    }

    /**
     * @param instream 流
     * @param fileName 文件名 上传类型
     * @return
     * @throws IOException
     * @Description (上传到OSS服务器 如果同名文件会覆盖服务器上的)
     */
    public static String uploadFile2OSS(InputStream instream, String fileDir, String fileName) {
        String urlPoint = null;
        int errorTimes = 0;
        OSSClient ossClient = null;
        try {
            while (errorTimes < 3) {

                try {
                    ClientConfiguration conf = new ClientConfiguration();
                    // 请求超时时间设置
                    conf.setConnectionTimeout(5000);
                    // 请求失败重试次数
                    conf.setMaxErrorRetry(3);
                    // 创建上传Object的Metadata
                    ObjectMetadata objectMetadata = new ObjectMetadata();
                    // objectMetadata.setContentLength(instream.available());
                    objectMetadata.setCacheControl("no-cache");
                    objectMetadata.setHeader("Pragma", "no-cache");
                    objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
                    objectMetadata.setContentDisposition("inline;filename=" + fileName);
                    // 上传文件
                    ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret, conf);
                    urlPoint = fileDir + currentYYYYMM + fileName;
                    PutObjectResult putResult = ossClient.putObject(bucketName, urlPoint, instream, objectMetadata);
                    String ret = putResult.getETag();
                    if (ret != null) {
                        LogUtil.info("oss上传成功 文件名:" + urlPoint);
                        return urlPoint;
                    }
                } catch (Exception e) {
                    errorTimes++;
                    LogUtil.info("oss上传异常 重试次数=" + errorTimes + "文件名:" + urlPoint);
                    LogUtil.error("oss上传异常", e);
                } finally {
                    if (ossClient != null) {
                        ossClient.shutdown();
                    }
                }
            }
        } finally {
            if (instream != null) {
                try {
                    instream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return urlPoint;
    }

    public static String deleteHead(final String base64) {
        if (base64.startsWith("data:") && base64.contains("base64,")) {
            return base64.substring(base64.indexOf("base64,") + 7);
        }
        return base64;
    }


    /**
     * 根据相对路径判断获取绝对路径
     *
     * @param filePath
     * @return
     */
    public static String getBaseUrl(String filePath) {
        if (filePath != null && !"".equals(filePath) && !filePath.startsWith("http")) {
            return OSS_URL + filePath;
        } else {
            return filePath;
        }
    }

    /**
     * 通过局域网获取文件
     *
     * @param filePath
     * @return
     */
    public static String getBaseUrlLocal(String filePath) {
        if (filePath != null && !"".equals(filePath) && !filePath.startsWith("http")) {
            return OSS_URL + filePath;
        } else {
            return filePath;
        }
    }

    /**
     * Description: 判断OSS服务文件上传时文件的contentType
     *
     * @param FilenameExtension 文件后缀
     * @return String
     */
    public static String getcontentType(String FilenameExtension) {
        if ("bmp".equalsIgnoreCase(FilenameExtension)) {
            return "image/bmp";
        }
        if ("gif".equalsIgnoreCase(FilenameExtension)) {
            return "image/gif";
        }
        if ("jpeg".equalsIgnoreCase(FilenameExtension) || "jpg".equalsIgnoreCase(FilenameExtension) || "png".equalsIgnoreCase(FilenameExtension)) {
            return "image/jpeg";
        }
        if ("html".equalsIgnoreCase(FilenameExtension)) {
            return "text/html";
        }
        if ("txt".equalsIgnoreCase(FilenameExtension)) {
            return "text/plain";
        }
        if ("vsd".equalsIgnoreCase(FilenameExtension)) {
            return "application/vnd.visio";
        }
        if ("pptx".equalsIgnoreCase(FilenameExtension) || "ppt".equalsIgnoreCase(FilenameExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if ("docx".equalsIgnoreCase(FilenameExtension) || "doc".equalsIgnoreCase(FilenameExtension)) {
            return "application/msword";
        }
        if ("xml".equalsIgnoreCase(FilenameExtension)) {
            return "text/xml";
        }
        return null;
    }

    public static boolean existFile(String rul) {
        OSSClient ossClient = null;
        try {
            ClientConfiguration conf = new ClientConfiguration();
            // 请求超时时间设置
            conf.setConnectionTimeout(5000);
            // 请求失败重试次数
            conf.setMaxErrorRetry(3);
            ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret, conf);
            return ossClient.doesObjectExist(bucketName, rul);
        } catch (Exception e) {
            return false;
        } finally {
            assert ossClient != null;
            ossClient.shutdown();
        }
    }

    public static void main(String[] args) {
        if (!existFile("trainingTrackData/202007/4901_20200721105458data.dat")) {
            log.error("不存在");
        }
    }
}